// Go 接口使用场景示例
package main

import (
	"fmt"
	"net/http"
)

// 场景 1：存储抽象
// 定义接口

// Storage 定义通用数据存储接口
type Storage interface {
	Save(data string) error
}

// MySQLStorage 实现

type MySQLStorage struct{}

func (m MySQLStorage) Save(data string) error {
	fmt.Println("Saving to MySQL:", data)
	return nil
}

// RedisStorage 实现
type RedisStorage struct{}

func (r RedisStorage) Save(data string) error {
	fmt.Println("Saving to Redis:", data)
	return nil
}

// 业务处理函数
func ProcessData(s Storage, data string) {
	s.Save(data)
}

// 场景 2：HTTP handler 接口实现

// MyHandler 实现 http.Handler 接口
type MyHandler struct{}

func (h MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, "Hello from MyHandler")
}

// 场景 3：日志抽象

type Logger interface {
	Log(msg string)
}

type ConsoleLogger struct{}
func (c ConsoleLogger) Log(msg string) {
	fmt.Println("[Console]", msg)
}

type FileLogger struct{}
func (f FileLogger) Log(msg string) {
	fmt.Println("[File]", msg) // 模拟写入文件
}

func DoSomething(logger Logger) {
	logger.Log("Doing something important")
}

// 场景 4：测试替换（Mock）

type Notifier interface {
	Send(to string, message string) error
}

type EmailNotifier struct{}
func (e EmailNotifier) Send(to string, msg string) error {
	fmt.Println("[Email] to:", to, "msg:", msg)
	return nil
}

type MockNotifier struct{}
func (m MockNotifier) Send(to string, msg string) error {
	fmt.Println("[Mock] to:", to, "msg:", msg)
	return nil
}

func NotifyUser(n Notifier) {
	n.Send("user@example.com", "Welcome!")
}

// 场景 5：插件架构 / 策略模式
type PaymentGateway interface {
	Pay(amount float64) error
}

type WeChatPay struct{}
func (w WeChatPay) Pay(amount float64) error {
	fmt.Println("Paying with WeChat:", amount)
	return nil
}

type AliPay struct{}
func (a AliPay) Pay(amount float64) error {
	fmt.Println("Paying with Alipay:", amount)
	return nil
}

func PayNow(pg PaymentGateway, amount float64) {
	pg.Pay(amount)
}

// main 函数用于演示调用
func main() {
	// 场景 1
	ProcessData(MySQLStorage{}, "User data")
	ProcessData(RedisStorage{}, "Cache data")

	// 场景 2
	go http.ListenAndServe(":8080", MyHandler{})
	fmt.Println("HTTP server running on http://localhost:8080")

	// 场景 3
	DoSomething(ConsoleLogger{})
	DoSomething(FileLogger{})

	// 场景 4
	NotifyUser(EmailNotifier{})
	NotifyUser(MockNotifier{})

	// 场景 5
	PayNow(WeChatPay{}, 88.8)
	PayNow(AliPay{}, 66.6)
}
